home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oh!X 2000 Spring
/
Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).7z
/
Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).bin
/
MIPSSIM
/
arith.c
next >
Wrap
C/C++ Source or Header
|
1999-12-02
|
10KB
|
482 lines
#include "define.h"
static void ADD64(ulong a1, ulong a0,
ulong b1, ulong b0,
int cin,
ulong *s1, ulong *s0,
int *cout)
{
ulong a1h,a1l;
ulong a0h,a0l;
ulong b1h,b1l;
ulong b0h,b0l;
ulong s1h,s1l;
ulong s0h,s0l;
a1h = (a1>>16)&0xffff;
a1l = (a1 )&0xffff;
a0h = (a0>>16)&0xffff;
a0l = (a0 )&0xffff;
b1h = (b1>>16)&0xffff;
b1l = (b1 )&0xffff;
b0h = (b0>>16)&0xffff;
b0l = (b0 )&0xffff;
s0l = a0l + b0l + cin;
s0h = a0h + b0h + ((s0l>>16)&0xffff);
s1l = a1l + b1l + ((s0h>>16)&0xffff);
s1h = a1h + b1h + ((s1l>>16)&0xffff);
*s0 = (s0h<<16)|(s0l&0xffff);
*s1 = (s1h<<16)|(s1l&0xffff);
*cout = (s1h>>16)&1;
}
void IADD64(ulong a1, ulong a0, ulong b1, ulong b0,
ulong *s1, ulong *s0, int *cy)
{
ADD64(a1, a0, b1, b0, 0, s1, s0, cy);
}
void ISUB64(ulong a1, ulong a0, ulong b1, ulong b0,
ulong *s1, ulong *s0, int *cy)
{
ADD64(a1, a0, ~b1, ~b0, 1, s1, s0, cy);
}
void NEG128(ulong a3, ulong a2, ulong a1, ulong a0,
ulong *b3, ulong *b2, ulong *b1, ulong *b0)
{
int carry;
ADD64(0L, 0L, ~a1, ~a0, 1, b1, b0, &carry);
ADD64(0L, 0L, ~a3, ~a2, carry, b3, b2, &carry);
}
void UMUL32(ulong a, ulong b, ulong *hi, ulong *lo)
{
ulong ah,al;
ulong bh,bl;
ulong m1,m2,l;
ulong M2,M3;
ah = a>>16;
al = a&0xffff;
bh = b>>16;
bl = b&0xffff;
l = al*bl;
m1 = ah*bl;
m2 = al*bh;
M3 = (m1&0xffff)+(m2&0xffff) +(l>>16) ;
M2 = (M3>>16)+(m1>>16)+(m2>>16);
*lo = ((m1+m2)<<16) +l ;
*hi = M2+ah*bh;
}
void UMUL64(ulong a1, ulong a0, ulong b1, ulong b0,
ulong *c3, ulong *c2, ulong *c1, ulong *c0)
{
ulong a0b0_h, a0b0_l;
ulong a0b1_h, a0b1_l;
ulong a1b0_h, a1b0_l;
ulong a1b1_h, a1b1_l;
ulong tmp1_h, tmp1_l;
ulong tmp2_h, tmp2_l;
ulong tmp3_h, tmp3_l;
ulong tmp;
int cy0,cy1,cy2;
UMUL32(a0, b0, &a0b0_h, &a0b0_l);
UMUL32(a0, b1, &a0b1_h, &a0b1_l);
UMUL32(a1, b0, &a1b0_h, &a1b0_l);
UMUL32(a1, b1, &a1b1_h, &a1b1_l);
ADD64(0, a0b0_h, a0b1_h, a0b1_l, 0, &tmp1_h, &tmp1_l, &cy0);
ADD64(tmp1_h, tmp1_l, a1b0_h, a1b0_l, 0, &tmp2_h, &tmp2_l, &cy1);
tmp = cy0+cy1;
ADD64(tmp, tmp2_h, a1b1_h, a1b1_l, 0, &tmp3_h, &tmp3_l, &cy2);
*c0 = a0b0_l;
*c1 = tmp2_l;
*c2 = tmp3_l;
*c3 = tmp3_h;
}
void UDIV64(ulong sh, ulong sl, ulong th, ulong tl,
ulong *qh, ulong *ql, ulong *rh, ulong *rl)
{
int i;
int carry,carry2;
ulong q_h, q_l, r_h, r_l;
q_h = 0L;
q_l = 0L;
for(i=0;i<64;i++){
ADD64(sh, sl, sh, sl, 0, &r_h, &r_l, &carry2);
sh = r_h;
sl = r_l;
ADD64(q_h, q_l, q_h, q_l, 0, &r_h, &r_l, &carry);
q_h = r_h;
q_l = r_l|carry2;
ADD64(q_h, q_l, ~th, ~tl, 1, &r_h, &r_l, &carry);
if(carry){ /* not borrow */
sl |= 1;
q_h = r_h;
q_l = r_l;
}
}
*qh = sh;
*ql = sl;
*rh = q_h;
*rl = q_l;
}
void UDIV32(ulong s, ulong t, ulong *q, ulong *r)
{
int i;
int carry;
ulong q_l, r_h, r_l;
q_l = 0L;
for(i=0;i<32;i++){
ADD64(q_l, s, q_l, s, 0, &r_h, &r_l, &carry);
q_l = r_h;
s = r_l;
ADD64(0, q_l, 0xffffffffL, ~t, 1, &r_h, &r_l, &carry);
if(carry){ /* not borrow */
s |= 1;
q_l = r_l;
}
}
*q = s;
*r = q_l;
}
void FDIV64(ulong sh, ulong sl, ulong th, ulong tl,
ulong *qh, ulong *ql, ulong *rh, ulong *rl,
int cnt)
{
int i;
int carry;
ulong q_h, q_l, r_h, r_l;
q_h = 0L;
q_l = 0L;
for(i=0;i<cnt;i++){
ADD64(sh, sl, ~th, ~tl, 1, &r_h, &r_l, &carry);
if(carry){ /* not borrow */
q_l |= 1;
sh = r_h;
sl = r_l;
}
ADD64(sh, sl, sh, sl, 0, &r_h, &r_l, &carry);
sh = r_h;
sl = r_l;
ADD64(q_h, q_l, q_h, q_l, 0, &r_h, &r_l, &carry);
q_h = r_h;
q_l = r_l;
}
*qh = q_h;
*ql = q_l;
*rh = sh;
*rl = sl;
}
void FSQRT64(ulong x1, ulong x0, ulong *y1, ulong *y0, ulong *r)
{
int i,d;
ulong q1, q0, b1, b0, a1, a0, s1, s0, t1, t0;
a1 = 0;
a0 = 0;
b1 = 0;
b0 = 0;
q1 = 0;
q0 = 0;
for(i=0;i<56;i++){
s1 = 0;
s0 = (x1>>23)&3;
ADD64(a1, a0, s1, s0, 0, &t1, &t0, &d);
a1 = t1;
a0 = t0;
ADD64(b1, b0, 0, 1, 0, &s1, &s0, &d);/* b+1 */
ADD64(a1, a0, ~s1, ~s0, 1, &t1, &t0, &d); /* t=a-(b+1) */
if(d){ /* not borrow */
q0 = q0+1;
a1 = t1;
a0 = t0;
ADD64(b1, b0, 0, 2, 0, &t1, &t0, &d); /* b+2 */
b1 = t1;
b0 = t0;
}
b1 = (b1<<1)|(b0>>31);
b0 = b0<<1;
q1 = (q1<<1)|(q0>>31);
q0 = q0<<1;
a1 = (a1<<2)|(a0>>30);
a0 = a0<<2;
x1 = (x1<<2)|(x0>>30);
x0 = x0<<2;
}
*y1=q1;
*y0=q0;
*r =(a1|a0);
}
void FSQRT32(ulong s, ulong *d, ulong *r)
{
int i;
int q,a,b;
a=0;
b=0;
q=0;
for(i=0;i<27;i++){
a += (s>>26)&3;
if((a-(b+1))>=0){
q=q+1;
a=a-(b+1);
b=b+2;
}
b=b<<1;
q=q<<1;
a=a<<2;
s=s<<2;
}
*d=q;
*r=a;
}
void RSHIFTS(ulong ihi, ulong ilo, int cnt,
ulong *ohi, ulong *olo)
{
ulong msk;
if(cnt>=64){
*ohi = 0L;
*olo = ((ihi|ilo)!=0);
}
else if(cnt>=32){
msk = (1<<(cnt-32))-1;
*ohi = 0L;
*olo = (ihi>>(cnt-32))|((ihi&msk)!=0)|(ilo!=0);
}
else if(cnt==0){
*ohi = ihi;
*olo = ilo;
}
else{
msk = (1<<cnt)-1;
*ohi = (ihi>>cnt);
*olo = (ihi<<(32-cnt))|(ilo>>cnt)|((ilo&msk)!=0);
}
}
void RSHIFTL(ulong ihi, ulong ilo, int cnt,
ulong *ohi, ulong *olo)
{
if(cnt>=64){
*ohi = 0L;
*olo = 0L;
}
else if(cnt>=32){
*ohi = 0;
*olo = (ihi>>(cnt-32));
}
else if(cnt==0){
*ohi = ihi;
*olo = ilo;
}
else{
*ohi = (ihi>>cnt);
*olo = (ihi<<(32-cnt))|(ilo>>cnt);
}
}
void RSHIFTA(ulong ihi, ulong ilo, int cnt,
ulong *ohi, ulong *olo)
{
int sgn;
sgn = ((ihi&0x80000000L)!=0);
if(cnt>=64){
*ohi = (sgn)? 0xffffffffL : 0L;
*olo = (sgn)? 0xffffffffL : 0L;
}
else if(cnt>=32){
*ohi = (sgn)? 0xffffffffL : 0L;
*olo = (((long)ihi)>>(cnt-32));
}
else if(cnt==0){
*ohi = ihi;
*olo = ilo;
}
else{
*ohi = (((long)ihi)>>cnt);
*olo = (ihi<<(32-cnt))|(ilo>>cnt);
}
}
void LSHIFT(ulong ihi, ulong ilo, int cnt,
ulong *ohi, ulong *omd, ulong *olo)
{
if(cnt>=96){
*ohi = 0L;
*omd = 0L;
*olo = 0L;
}
else if(cnt>=64){
*ohi = ilo << (cnt-64);
*omd = 0L;
*olo = 0L;
}
else if(cnt>32){
*ohi = (ihi<<(cnt-32))|(ilo>>(64-cnt));
*omd = (ilo<<(cnt-32));
*olo = 0L;
}
else if(cnt==32){
*ohi = ihi;
*omd = ilo;
*olo = 0L;
}
else if(cnt==0){
*ohi = 0L;
*omd = ihi;
*olo = ilo;
}
else{
*ohi = (ihi>>(32-cnt));
*omd = (ihi<<cnt)|(ilo>>(32-cnt));
*olo = (ilo<<cnt);
}
}
int CLZ32(ulong a)
{
return ((a&0xffffffffL)==0)? 32:
((a&0xfffffffeL)==0)? 31:
((a&0xfffffffcL)==0)? 30:
((a&0xfffffff8L)==0)? 29:
((a&0xfffffff0L)==0)? 28:
((a&0xffffffe0L)==0)? 27:
((a&0xffffffc0L)==0)? 26:
((a&0xffffff80L)==0)? 25:
((a&0xffffff00L)==0)? 24:
((a&0xfffffe00L)==0)? 23:
((a&0xfffffc00L)==0)? 22:
((a&0xfffff800L)==0)? 21:
((a&0xfffff000L)==0)? 20:
((a&0xffffe000L)==0)? 19:
((a&0xffffc000L)==0)? 18:
((a&0xffff8000L)==0)? 17:
((a&0xffff0000L)==0)? 16:
((a&0xfffe0000L)==0)? 15:
((a&0xfffc0000L)==0)? 14:
((a&0xfff80000L)==0)? 13:
((a&0xfff00000L)==0)? 12:
((a&0xffe00000L)==0)? 11:
((a&0xffc00000L)==0)? 10:
((a&0xff800000L)==0)? 9:
((a&0xff000000L)==0)? 8:
((a&0xfe000000L)==0)? 7:
((a&0xfc000000L)==0)? 6:
((a&0xf8000000L)==0)? 5:
((a&0xf0000000L)==0)? 4:
((a&0xe0000000L)==0)? 3:
((a&0xc0000000L)==0)? 2:
((a&0x80000000L)==0)? 1:
0;
}
int CLZ64(ulong ah, ulong al)
{
int clz;
clz = CLZ32(ah);
if(clz<32)
return clz;
clz = CLZ32(al);
return clz+32;
}
int CLO32(ulong a)
{
return CLZ32(~a);
}
int CLO64(ulong ah, ulong al)
{
return CLZ64(~ah, ~al);
}
void CMP64(ulong sh, ulong sl, ulong th, ulong tl, int *lt, int *eq)
{
int s, t, cy;
ulong dh, dl;
s = ((sh&0x80000000L)!=0L);
t = ((th&0x80000000L)!=0L);
*eq = (sh==th)&&(sl==tl);
if((s)&&(!t)){
*lt = 1;
}
else if((!s)&&(t)){
*lt = 0;
}
else{
ISUB64(sh, sl, th, tl, &dh, &dl, &cy);
*lt = ((dh&0x80000000L)!=0L);
}
}
void ACMP64(ulong sh, ulong sl, ulong th, ulong tl, int *lt, int *eq)
{
int s, t, e, cy;
ulong dh, dl;
s = ((sh&0x80000000L)!=0L);
t = ((th&0x80000000L)!=0L);
e = (sh==th)&&(sl==tl);
*eq = e;
if((s)&&(!t)){
*lt = 1;
}
else if((!s)&&(t)){
*lt = 0;
}
else{
ISUB64(sh, sl, th, tl, &dh, &dl, &cy);
if(s&&t)
*lt = (cy&&(!e));
else
*lt = ((!cy)&&(!e));
}
}
void UCMP64(ulong sh, ulong sl, ulong th, ulong tl, int *lt, int *eq)
{
int cy;
ulong dh, dl;
*eq = (sh==th)&&(sl==tl);
ISUB64(sh, sl, th, tl, &dh, &dl, &cy);
*lt = (!cy);
}
void INEG64(ulong sh, ulong sl, ulong *dh, ulong *dl)
{
int cy;
ISUB64(0L, 0L, sh, sl, dh, dl, &cy);
}
void IADD96(ulong s2, ulong s1, ulong s0,
ulong t2, ulong t1, ulong t0,
ulong *d2, ulong *d1, ulong *d0)
{
int cy;
ADD64(s1, s0, t1, t0, 0, d1, d0, &cy);
*d2 = s2+t2+(ulong)cy;
}